package com.kingshit.aihaiguitang.service.impl;

import com.kingshit.aihaiguitang.manager.AIManager;
import com.kingshit.aihaiguitang.model.ChatRoom;
import com.kingshit.aihaiguitang.service.ChatService;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class ChatServiceImpl implements ChatService {
    @Resource
    private AIManager aiManager;

    final Map<Long, List<ChatMessage>> globalMessagesMap = new HashMap<>();

    /**
     * 聊天
     *
     * @param roomId 聊天室id
     * @param message 用户自己输入的信息
     * @return
     */
    @Override
    public String doChat(Long roomId, String message) {
        // 1. 准备消息列表（关联历史上下文）
        // 系统预设 Prompt
        final String systemPrompt = "角色设定\n" +
                "你是一位专业的海龟汤游戏主持人，负责出题和引导玩家推理。你的任务是：\n" +
                "1. 提供一道海龟汤谜题的“汤面”（故事表面描述）。\n" +
                "2. 根据玩家的提问，仅回答“是”、“不是”或“与此无关”。\n" +
                "3. 在特定情况下结束游戏并揭示“汤底”（故事真相）。\n" +
                "游戏流程\n" +
                "1. 当玩家输入“开始”时，你需立即提供一道海龟汤谜题的“汤面”。\n" +
                "2. 玩家会依次提问，你只能回答以下三种之一：\n" +
                "  ○ 是：玩家的猜测与真相相符。\n" +
                "  ○ 不是：玩家的猜测与真相不符。\n" +
                "  ○ 与此无关：玩家的猜测与真相无直接关联。\n" +
                "3. 在以下情况下，你需要主动结束游戏并揭示“汤底”：\n" +
                "  ○ 玩家明确表示“不想玩了”、“想要答案”或类似表达。\n" +
                "  ○ 玩家几乎已经还原故事真相，或所有关键问题都已询问完毕。\n" +
                "  ○ 玩家输入“退出”。\n" +
                "  ○ 玩家连续提问 10 次仍未触及关键信息，或表现出完全无头绪的状态。\n" +
                "注意事项\n" +
                "1. 汤面设计：谜题应具有悬疑、恐怖的特点，且逻辑严密，最好是网络热门海龟汤，不要自己编造。\n" +
                "2. 回答限制：严格遵守“是”、“不是”或“与此无关”的回答规则，不得提供额外提示。\n" +
                "3. 结束时机：在符合结束条件时，及时揭示“汤底”，避免玩家陷入无效推理。\n" +
                "4. 当你决定结束时，必须在结束的消息中包含【游戏已结束】\n" +
                "示例\n" +
                "● 玩家输入：“开始”\n" +
                "● AI 回复（汤面）： “有一个女孩独自在家，陪伴她的只有爱犬，半夜她听到了水滴声，她害怕，于是把手放到了床边，让爱犬舔了舔她的手，第二天，狗死了。”\n" +
                "● 玩家提问：“狗被她毒死了吗？”\n" +
                "● AI 回复：“不是。”\n" +
                "● 玩家提问：“她是盲人吗？”\n" +
                "● AI 回复：“与此无关。”\n" +
                "● 玩家提问：“房间里面有其他人吗？”\n" +
                "● AI 回复：“是。”\n" +
                "● 玩家输入：“退出。”\n" +
                "● AI 回复（汤底）： “女孩独居，有一天晚上有个小偷潜入家里，把狗杀死吊在天花板上，滴水声是狗在滴血，舔她手的也不是她的狗，而是那个人。”";
        List<ChatMessage> messages = new ArrayList<>();
        // 系统消息(只需要添加一次)
        final ChatMessage systemMessage = ChatMessage.builder().role(ChatMessageRole.SYSTEM).content(systemPrompt).build();
        final ChatMessage userMessage = ChatMessage.builder().role(ChatMessageRole.USER).content(message).build();

        // 判断对话是否合法
        if (!message.contains("开始") && globalMessagesMap.isEmpty()) {
            throw new RuntimeException("请先开始游戏！");
        }

        // 判断是否首次对话
        if (message.contains("开始") && !globalMessagesMap.containsKey(roomId)) {
            // 首次对话，需要添加房间号，并且添加系统预设到消息列表中。
            globalMessagesMap.put(roomId, messages);
            messages.add(systemMessage);
        } else {
            // 非首次对话，直接从全局消息列表(或数据库)中根据房间id获取消息列表。
            messages = globalMessagesMap.get(roomId);
        }

        // 添加用户消息到消息列表中。
        messages.add(userMessage);

        // 2. 调用 AI
        String answer = aiManager.doChat(messages);

        final ChatMessage assistantMessage = ChatMessage.builder().role(ChatMessageRole.ASSISTANT).content(answer).build();
        // 把 AI助手的回答添加到消息列表中
        messages.add(assistantMessage);

        // 如果对话结束，则从全局消息列表中移除该房间的消息列表。
        if (answer.contains("游戏已结束")) {
            globalMessagesMap.remove(roomId);
        }

        // 返回消息
        return answer;
    }

    /**
     * 获取聊天室列表
     *
     * @return
     */
    @Override
    public List<ChatRoom> getChatRoomList() {
        List<ChatRoom> chatRooms = new ArrayList<>();
        for (Map.Entry<Long, List<ChatMessage>> roomIdMsgListEntry : globalMessagesMap.entrySet()) {
            ChatRoom chatRoom = new ChatRoom();
            chatRoom.setRoomId(roomIdMsgListEntry.getKey());
            chatRoom.setChatMessageList(roomIdMsgListEntry.getValue());
            chatRooms.add(chatRoom);
        }
        return chatRooms;
    }
}
